/*
-----------------------------------------------------------------------------
This source file is part of FRAPPER
research.animationsinstitut.de
sourceforge.net/projects/frapper

Copyright (c) 2008-2009 Filmakademie Baden-Wuerttemberg, Institute of Animation 

This program is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the Free Software
Foundation; version 2.1 of the License.

This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place - Suite 330, Boston, MA 02111-1307, USA, or go to
http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
-----------------------------------------------------------------------------
*/

//!
//! \file "ViewNode.cpp"
//! \brief Implementation file for ViewNode class.
//!
//! \author     Stefan Habel <stefan.habel@filmakademie.de>
//! \author     Nils Zweiling <nils.zweiling@filmakademie.de>
//! \version    1.0
//! \date       27.04.2009 (last updated)
//!

#include "ViewNode.h"
#include <Ogre.h>
#if (OGRE_PLATFORM  == OGRE_PLATFORM_WIN32)
#include <windows.h>
#endif


///
/// Constructors and Destructors
///


//!
//! Constructor of the ViewNode class.
//!
//! \param name The name for the new node.
//! \param parameterRoot A copy of the parameter tree specific for the type of the node.
//!
ViewNode::ViewNode ( const QString &name, ParameterGroup *parameterRoot ) :
    CurveEditorDataNode(name, parameterRoot),
    m_stageIndex(1),
    m_view(false)
{
}


//!
//! Destructor of the ViewNode class.
//!
//! Defined virtual to guarantee that the destructor of a derived class
//! will be called if the instance of the derived class is saved in a
//! variable of its parent class type.
//!
ViewNode::~ViewNode ()
{
    if (m_view)
        // notify connected objects that this node is no longer viewed
        emit viewSet(m_stageIndex, 0);
}


///
/// Public Functions
///


//!
//! Returns the index of the stage in which this node is contained.
//!
//! \return The index of the stage in which this node is contained.
//!
unsigned int ViewNode::getStageIndex () const
{
    return m_stageIndex;
}


//!
//! Sets the index of the stage in which this node should be contained.
//!
//! \param stageIndex The index of the stage in which this node should be contained.
//!
void ViewNode::setStageIndex ( unsigned int stageIndex )
{
    if (stageIndex == m_stageIndex)
        return;

    if (m_view)
        // notify connected objects that the node is no longer contained in its old stage
        emit viewSet(m_stageIndex, 0);

    m_stageIndex = stageIndex;

    if (m_view)
        // notify connected objects that the node is now contained in the new stage
        emit viewSet(m_stageIndex, this);
}


//!
//! Returns whether the result of this node should be displayed in the
//! viewport.
//!
//! \return True if the result of this node should be displayed in the viewport, otherwise False.
//!
bool ViewNode::isViewed () const
{
    return m_view;
}


//!
//! Returns the scene node that contains scene objects created or modified
//! by this node.
//!
//! The default implementation returns 0.
//! To be implemented in derived classes that work on scene geometry data.
//!
//! \return The scene node containing objects created or modified by this node.
//!
Ogre::SceneNode * ViewNode::getSceneNode ()
{
    return 0;
}


//!
//! Returns the image that is generated by this node.
//!
//! The default implementation returns an empty texture pointer.
//! To be implemented in derived classes that work on image data.
//!
//! \return The image that is generated by this node.
//!
Ogre::TexturePtr ViewNode::getImage ()
{
    return Ogre::TexturePtr(0);
}


///
/// Public Slots
///


//!
//! Sets whether this node should be evaluated in the network.
//!
//! \param evaluate The new value for eval flag of this node.
//!
void ViewNode::setEvaluate ( bool evaluate )
{
    if (m_evaluate != evaluate) {
        m_evaluate = evaluate;

        // notify connected objects that the node has changed
        emit nodeChanged();
    }
}


//!
//! Sets whether the result of this node should be displayed in the
//! viewport.
//!
//! \param view The new value for view flag of this node.
//! \param suppressViewSetSignal Flag to control whether the viewSet signal is emitted from this function.
//!
void ViewNode::setView ( bool view, bool suppressViewSetSignal /* = false */ )
{
	// TODO: NILZ: problem when loading scenes with nodes which have no view flag set -> nodeChanged signal is not emitted -> better solution
    if (m_view != view) {
        m_view = view;

        if (!suppressViewSetSignal)
            if (m_view)
                // notify connected objects that this node has been set to be viewed
                emit viewSet(m_stageIndex, this);
            else
                // notify connected objects that this node is no longer viewed
                emit viewSet(m_stageIndex, 0);

        // notify connected objects that the node has changed
        emit nodeChanged();
    }
}


///
/// Protected Functions
///


//!
//! Adds the given parameter as output parameter to this view node.
//!
//! The viewNodeUpdated signal will be emitted when the given parameter is
//! made dirty.
//!
//! \param outputParameter The parameter that when dirtied will trigger the viewNodeUpdated signal.
//!
void ViewNode::addOutputParameter ( Parameter *outputParameter )
{
    if (!outputParameter)
        return;

    outputParameter->setPinType(Parameter::PT_Output);
    outputParameter->setNode(this);
    outputParameter->setDirty(true);

    getParameterRoot()->addParameter(outputParameter);

    QObject::connect(outputParameter, SIGNAL(dirtied()), SLOT(checkViewFlag()));
}


//!
//! Request a redraw of the current ogre scene.
//!
void ViewNode::requestRedraw ()
{
    emit triggerRedraw ();
}


///
/// Private Slots
///


//!
//! Checks if the view flag is currently set for this node and if so
//! notifies connected objects that the view node has been updated by
//! emitting the viewNodeUpdated signal.
//!
void ViewNode::checkViewFlag ()
{
    // check if the view flag is currently set for this node
    if (m_view)
        // notify connected objects that the view node has been updated
        emit viewNodeUpdated();
}


